package nio;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.DatagramChannel;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.WritableByteChannel;

public class Channel {

	public static void main(String[] args) throws IOException {
		t5();
	}
	public static void t1() throws Exception{
		/**
		 * 所有的socket通道都是双向的,可读也可写
		 * socket and pipe可以用阻塞的方式读写
		 * 通道不能被重用,代表一个特定的io
		 * 如果通道被interrupte那么就关闭通道
		 */
		SocketChannel socket=SocketChannel.open();
		socket.connect(new InetSocketAddress("127.0.0.1", 8989));
		ServerSocketChannel serverSocket=ServerSocketChannel.open();
		serverSocket.socket().bind(new InetSocketAddress(8989));
		DatagramChannel dgc=DatagramChannel.open();
		/**
		 * File通道注意是单向的,要么只可读,要么只可写
		 * 只可以用非阻塞的方式读写
		 * 文件系统是线程安全的
		 */
		RandomAccessFile raf=new RandomAccessFile("D:/test.txt", "rw");
		FileChannel fileChannel=raf.getChannel();
		if(fileChannel.isOpen()){
			fileChannel.close();
		}
	}
	public static void t2() throws Exception{
		ByteBuffer byteBuffer1=ByteBuffer.allocate(8*2);
		ByteBuffer byteBuffer2=ByteBuffer.allocate(8*2);
		ByteBuffer[] byteBufferUnion={byteBuffer1,byteBuffer2};
		RandomAccessFile raf=new RandomAccessFile("D:/test.txt", "rw");
		FileChannel fileChannel=raf.getChannel();
		//scatter发散,如果被读写的buffer为数组,则offset为数组的下标,而不是buffer里面的position
		fileChannel.read(byteBufferUnion);
		//gatter聚集
		fileChannel.write(byteBufferUnion);
		//如果为true把文件的元数据也更新,eg:最近更新时间
		fileChannel.force(true);
		//锁定的位子,锁定大小,是否共享锁
		//fileChannel.lock(position, size, shared);
		//fileChannel.map(mode, position, size);
	}
	public static void t3() throws IOException{
		FileOutputStream out=new FileOutputStream("D:/test.txt");
		FileChannel fileChannel=out.getChannel();
		fileChannel.write(ByteBuffer.wrap("我是一个兵".getBytes()));
		fileChannel.close();
		out.close();
		
		FileInputStream input=new FileInputStream("D:/test.txt");
		FileChannel fileChannelInput=input.getChannel();
		ByteBuffer byteBuffer=ByteBuffer.allocate(64);
		fileChannelInput.read(byteBuffer);
		byteBuffer.flip();
		System.out.println(new String(byteBuffer.array()));
		//创建一个大小等于填充大小的数组
		byte[] bytes=new byte[byteBuffer.limit()];
		//把其读取到bytes
		byteBuffer.get(bytes);
		System.out.println(new String(bytes));
		fileChannelInput.close();
		input.close();
		
	}
	public static void t4() throws IOException{
		//只读
		ReadableByteChannel read=Channels.newChannel(System.in);
		//可写
		WritableByteChannel write=Channels.newChannel(System.out);
		ByteBuffer dst=ByteBuffer.allocate(32);
		read.read(dst);
		dst.flip();
		write.write(dst);
		write.close();
		read.close();
	}
	public static void  t5() throws IOException{
		/**
		 * 先读满byte1,再读byte2
		 */
		ByteBuffer byteBuffer1=ByteBuffer.allocate(10);
		ByteBuffer byteBuffer2=ByteBuffer.allocate(64);
		ByteBuffer[] srcs={byteBuffer1,byteBuffer2};
		FileInputStream input=new FileInputStream("D:/test.txt");
		FileChannel fileChannel=input.getChannel();
		byteBuffer2.put("string".getBytes());
		fileChannel.read(srcs);
		
		byteBuffer1.flip();
		fileChannel.force(true);
		System.out.println(new String(byteBuffer1.array()));
		byteBuffer2.flip();
		System.out.println(new String(byteBuffer2.array()));
		
		fileChannel.close();
		input.close();
	}

}
